import { h, defineComponent, App } from 'vue';
import { ElEmpty, ElInput } from 'element-plus';
import { componentMap } from '@/components/BasicModalForm/componentMap';
import type { Component as ComponentType } from '@/components/BasicModalForm/types';
import VxeUI from 'vxe-pc-ui';
import { deepMerge } from '@/utils';
import { omit } from 'lodash-es';
import VxeUIPluginRenderElement from '@vxe-ui/plugin-render-element';
import VxeUIPluginExportXLSX from '@vxe-ui/plugin-export-xlsx';
import ExcelJS from 'exceljs';
import { vxeTableGlobConfig, vxeUIGlobICON } from '@/config/vxe-table';
import VXETable from 'vxe-table';
import '@vxe-ui/plugin-render-element/dist/style.css';
import '@/styles/vxe-table.scss';
import '@/styles/index.scss'; // global css
// 引入自定义主题样式
import emptyImage from '@/assets/images/empty.png';

// 定义带$前缀的渲染器与Element组件的映射关系
const rendererMap: Record<string, string> = {
  $select: 'ElSelect',
  $switch: 'ElSwitch',
  // 以下特殊渲染器不要直接引用
  // $input: "ElInput",
  // $buttons: "ElButtons",
  // $button: "ElButton",
};

const EmptyRender = defineComponent({
  render(ctx: { $props: any; $attrs: any }) {
    const image =
      ctx.$attrs.image ||
      'https://gw.alipayobjects.com/mdn/miniapp_social/afts/img/A*pevERLJC9v0AAAAAAAAAAABjAQAAAQ/original';
    return h(
      ElEmpty,
      deepMerge(
        {
          description: '暂无数据~',
          image: ctx.$attrs.isPc ? emptyImage : image,
        },
        ctx.$props,
        ctx.$attrs,
      ),
    );
  },
});

/**
 * @description VXE表格与Element Plus组件集成
 * @author Generated by AI
 */
export function setupVxe(app: App) {
  // 先使用Element Plus渲染器插件
  VxeUI.use(VxeUIPluginRenderElement);
  VxeUI.use(VxeUIPluginExportXLSX, {
    ExcelJS,
  });
  VxeUI.setIcon(vxeUIGlobICON);

  VxeUI.setIcon(vxeUIGlobICON);
  VxeUI.setConfig(vxeTableGlobConfig);
  app.use(VxeUI);
  app.use(VXETable);

  // VxeUI 添加自定义空状态渲染
  VxeUI.renderer.add('RenderEmpty', {
    renderTableEmpty(renderOpts: any, params: any) {
      const { attrs, props } = renderOpts;
      let isPc = false;
      try {
        const el = params.$table.xeGrid.getEl();
        // 是否classList 中有 com-vxe
        if (el.classList.contains('com-vxe')) {
          isPc = true;
        }
      } catch (e) {
        // 忽略元素获取失败的错误
      }
      return h(EmptyRender, {
        ...Object.assign({ isPc }, attrs || {}, props || {}),
      });
    },
  });

  // !VxeUI 添加自定义表单组件 列入 apiSelect api** 数据代理这些 或者 FileUpload 文件上传等等
  componentMap.forEach((com) => {
    // 忽略起始 El or el- 命名的组件
    const componentName = `${com.name}`;
    if (componentName?.startsWith('El') || componentName?.startsWith('el-') || !componentName) {
      return;
    }
    console.log(
      `%c VxeUI.renderer.add: %c ${componentName} `,
      'padding: 2px 4px; color: #333; background: #FFF; font-weight: bold;font-size: 14px',
      'padding: 2px 4px; border-radius: 3px 0 0 3px; color: #42c02e; font-weight: 400;font-size: 14px',
    );
    // 创建渲染器
    VxeUI.renderer.get(componentName) === null &&
      VxeUI.renderer.add(componentName, {
        // 项显示模板
        renderFormItemContent(renderOpts: any, params) {
          const Comp = componentMap.get(com.name as ComponentType) as ReturnType<
            typeof defineComponent
          >;
          const { props } = renderOpts;
          const change = (...a: any[]) => {
            params.data[params.field] = a[0];
            params.$form.validateField(params.field as string);
            props?.onChange?.(...a);
          };
          return (
            <Comp
              w-full
              v-model={params.data[params.field]}
              onChange={change}
              v-slots={renderOpts.slots}
              {...(omit(props, 'onChange') ?? {})}
            />
          );
        },
      });
  });

  // 重写原生$开始的渲染器，直接引用ElementUI相对应的组件，主要以 input 和 select 为主，全项目查询条件基本上都是用的这两个，所以直接使用Element组件的渲染器
  try {
    // 将带$前缀的渲染器映射到Element组件对应的渲染器
    Object.entries(rendererMap).forEach(([dollarName, elName]) => {
      // 获取Element组件的渲染器实现
      const $originalRenderer = VxeUI.renderer.get(dollarName);
      const ElOriginalRenderer = VxeUI.renderer.get(elName);

      if (!$originalRenderer) {
        console.warn(`未找到渲染器: ${dollarName}`);
        return;
      }

      if (!ElOriginalRenderer) {
        console.warn(`未找到渲染器elementUI: ${elName}`);
        return;
      }

      VxeUI.renderer.delete(dollarName);
      // 注册$前缀渲染器，使用原始Element组件渲染器的实现
      VxeUI.renderer.add(dollarName, ElOriginalRenderer);
      console.log(`已映射渲染器: ${dollarName} -> ${elName}`);
    });
    console.log('VXE表格Element Plus渲染器映射完成');
  } catch (e) {
    console.error('设置渲染器失败', e);
  }

  // 特殊手动替换 $input 渲染器
  // 先检查是否存在，避免错误
  const hasInput = VxeUI.renderer.get('$input') !== null;
  const $OldInput = hasInput ? VxeUI.renderer.get('$input') : {};

  // 如果存在，先删除它
  if (hasInput) {
    VxeUI.renderer.delete('$input');
  }

  // 创建新的渲染器 - 只使用必要的renderFormItemContent方法
  VxeUI.renderer.add('$input', {
    // 重写renderFormItemContent实现，参考plugin-render-element
    renderFormItemContent(renderOpts: any, params: any) {
      const { data, field, column } = params;
      const { props = {}, attrs = {}, events = {}, slots } = renderOpts;
      // 获取当前字段的值 (参考plugin-render-element的实现)
      const fieldValue = data[field];

      /**
       * 处理属性
       */
      // 合并基础属性和附加属性
      const inputProps: Record<string, any> = {
        // 合并attrs和props
        ...attrs,
        ...props,
        // 默认属性
        modelValue: fieldValue,
        placeholder: props.placeholder || `请输入${column?.title || ''}`,
        clearable: props.clearable !== false, // 默认可清除
        size: props.size || attrs.size || column?.params?.size || 'default',
        disabled: props.disabled || attrs.disabled || false,
        readonly: props.readonly || attrs.readonly || false,
        // 根据类型添加特定属性
        type: props.type || attrs.type || 'text',
        maxlength: props.maxlength || attrs.maxlength,
        showWordLimit: props.showWordLimit || attrs.showWordLimit,
      };

      /**
       * 构建事件处理
       */
      // 事件处理对象
      const ons: Record<string, (...args: any[]) => void> = {};

      // 处理用户自定义事件
      if (events) {
        Object.keys(events).forEach((key) => {
          // 转换事件名称为on开头的驼峰格式
          const onKey = 'on' + key.charAt(0).toUpperCase() + key.slice(1);
          ons[onKey] = (...args: any[]) => {
            events[key](params, ...args);
          };
        });
      }

      // 处理v-model双向绑定事件
      ons['onUpdate:modelValue'] = (value: any) => {
        // 更新数据
        data[field] = value;

        // 触发表单校验
        if (params.$form && params.$form.validateField) {
          params.$form.validateField(field as string);
        }

        // 处理内置更新事件
        if (events['update:modelValue']) {
          events['update:modelValue'](params, value);
        }
      };

      // 处理Input特有的input事件
      ons['onInput'] = (value: any) => {
        // 如果有自定义事件，也触发它
        if (events.input) {
          events.input(params, { value });
        }
      };

      // 合并所有属性
      const allProps = {
        ...inputProps,
        ...ons,
      };

      /**
       * 处理插槽
       */
      // 处理插槽内容
      const vSlots: Record<string, any> = {};

      if (slots) {
        Object.keys(slots).forEach((name) => {
          const originalSlot = slots[name];
          vSlots[name] = (scope: any) => {
            return originalSlot ? originalSlot({ ...scope }) : null;
          };
        });
      }

      // 返回渲染的ElInput组件
      return h(ElInput, allProps, vSlots);
    },
    ...omit($OldInput, 'renderFormItemContent'), // 保留其他可能存在的方法
  });
}
